<?php

declare(strict_types=1);

namespace app\core;

use Swoole\Http\Server;
use Swoole\Timer;
use app\core\Db as mainDb;
use app\core\DB\Test\Db;
use app\core\RedisDB;
use Swoole\Event;

class System
{
    
    private $server = null;
    private $serverSec=null;
    public function __construct()
    {
        $this->server = new Server("127.0.0.1", 8866);
        $this->serverSec=$this->server->listen("127.0.0.1", 8877, SWOOLE_SOCK_TCP);
        $this->server->set([
            // 'reactor_num'   => 1,
            'log_file' =>  __DIR__.'/../log.log',
            'log_date_format' => '%Y-%m-%d %H:%M:%S',
            'daemonize' => true,
            'worker_num'=>2,
           
            // 'max_wait_time'=>60,
            'reload_async' => true,
            'enable_coroutine' => true,
            'task_worker_num' => 4,
            'task_enable_coroutine' => true,
            'dispatch_mode' => 3
        ]);
        $this->serverSec->set([
            'open_http_protocol' => false, 
        ]);
        $this->server->on('WorkerStart', [$this, 'workerStart']);
        $this->server->on('request', [$this, 'request']);
        $this->server->on('Finish', [$this, 'finish']);
        $this->server->on('Task', [$this, 'task']);
        $this->server->on('start', [$this, 'start']);
        $this->server->on('managerStart', [$this, 'managerStart']);
        $this->serverSec->on('Receive', [$this, 'receive']);
        // $this->server->on('receive', [$this, 'receive']);
    }
    public function workerStart($server, $worker_id)
    {
        if ($server->taskworker) {
            $title = "order:task-$worker_id";
        } else {
            $title = "order:worker-$worker_id";
        }
        include_once  __DIR__.'/../init.php';

        $pid = getmypid();
        cli_set_process_title($title);
       
        mainDb::getInstance();
        Route::init();
        // RedisDB::getInstance();
        $db = (new Db());
        Timer::after(100, function () use ($db) {
            $db->ping();
            Timer::tick(30000, function () use ($db) {
                
                $db->ping();
            });
            // Event::wait();
        });
    }
    public function request($request, $response)
    {
        
        Route::run($request, $response);
       
        
    }
    public function receive($server, int $fd, int $reactorId, string $data){
       
        $task_id=$server->task($data,-1,null);
        $server->send($fd, "Task distrubted id:$task_id\n");
    }
    public function finish($server,$task_id,$data)
    {
       echo "Task#$task_id finished, data_len=" . strlen($data) . PHP_EOL;
    }
    public function task(\Swoole\Server $server, $data)
    {
  
        $body=json_decode(trim($data->data),true);
       
        if(true === array_key_exists('class',$body)){
            
            $class="\\".$body['class'];
            $method=$body['method'];
            $params=$body['params'];
            $bus=(new $class())->$method(...$params);
          
        }
       
    }
    public function start($server)
    {
        $title = "order:master";
      
        cli_set_process_title($title);
    }
    public function managerStart($server)
    {
        $title = "order:manager";
       
        cli_set_process_title($title);
    }

    public function run(){
        $this->server->start();
    }
}
